import { sys } from "cc";
import { CustomEventListener } from "../data/CustomEventListener";

export interface IGameHttpRequest {
    eventName: string,
    url: string,
    method: string,
    header?: any,
    timeout?: number,
    reqData?: any,
    responseType?: XMLHttpRequestResponseType
}

export class DoHttp {
    private _xhrXHR: XMLHttpRequest| null = null;
    private _responseType: XMLHttpRequestResponseType = "json";
    private _method: string = "GET";
    private _url: string = "";
    private _eventName: string | null = null;
    private _timeout: number = 10000;
    private _extendReqHeaders : any | null = null;
    private _requestData: any | null = null;
    private _failHandle: (status: number, eventName: string) => void = null;
    private _succHandle: (data: any, eventName: string) => void = null;
    /**
     *
     */
    constructor(request: IGameHttpRequest,
        failHandle: (status: number, eventName: string) => void,
        succHandle: (data: any, eventName: string) => void) {

        this._xhrXHR = null;
        this._failHandle = failHandle;
        this._succHandle = succHandle;
        this.init(request);
    }

    init(request: IGameHttpRequest) {
        if(!request.url) {
            console.warn("http none url init, return");
            return false;
        }
        if (request.url.slice(0, 4) !== "http") {
            console.warn("http err url init, return:"+request.url);
            return false;
        }
        this.setEventName(request.eventName);
        this.setUrl(request.url);
        this.setMethod(request.method);
        this.setHeaders(request.header);
        if (request.method === "POST" && request.reqData) {
            this.setReqData(request.reqData);
        }
        if (request.timeout) {
            this.setReqTimeout(request.timeout);
        }
        if (request.responseType) {
            this.setRespType(request.responseType);
        }
        return true;
    }

    setEventName(eventName: string) {
        this._eventName = eventName;
    }

    setUrl(url: string) {
        this._url = url;
    }

    setMethod(method: string) {
        this._method = method;
    }

    setReqTimeout(timeout: number) {
        this._timeout = timeout;
    }

    setReqData(reqData: any) {
        this._requestData = reqData;
    }

    setRespType(responseType: XMLHttpRequestResponseType) {
        this._responseType = responseType;

    }

    setHeaders(headers: any) {
        if (!headers) return;
        console.log("http setHeaders headers : " + JSON.stringify(headers));
        this._extendReqHeaders = headers;
        // if (!this.http_connector) return false;

        // for (var key in headers) {
        //     var header = headers[key];
        //     if (header == undefined) continue;
        //     cc.log("http @@@@ set_headers @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 【" + key + "】 : " + JSON.stringify(header));
        //     this.http_connector.setRequestHeader(key, header);
        // }

        // return true;
    }

    request() {
        this.validate();
        this._xhrXHR = new XMLHttpRequest();
        this._xhrXHR.onreadystatechange = this.doXHREvent.bind(this);
        this._xhrXHR.ontimeout = this.doXHRTimeout.bind(this);
        this._xhrXHR.open(this._method, this._url);
        for (var key in this._extendReqHeaders) {
            var header = this._extendReqHeaders[key];
            if (!header) continue;
            console.log("http request header 【" + key + "】 : " + JSON.stringify(header));
            this._xhrXHR.setRequestHeader(key, header);
        }
        if (sys.isNative) {
            this._xhrXHR.setRequestHeader('Accept-Encoding','gzip,deflate');
        }
        try {
            this._xhrXHR.timeout = this._timeout
            this._xhrXHR.responseType = this._responseType;      //----默认返回json
            this._responseType = "";
        }
        catch (error) //这是IE
        {
            // this._responseType = response_type || "json"
        }

        if (this._requestData) {
            this._xhrXHR.send(encodeURI(this._requestData).replace(/\+/g, '%2B'))     //发送请求
        } else {
            this._xhrXHR.send()                                                      //发送请求
        }
    }

    doXHREvent() {
        if (this._xhrXHR.readyState === 4 && (this._xhrXHR.status >= 200 && this._xhrXHR.status < 207)) {
            if (this._xhrXHR.responseType !== "json" && (this._responseType !== "json")){
                // 暂时只处理json格式数据
                this._xhrXHR = null;
                return;
            }
            let response = this._xhrXHR.response;
            let response_status = this._xhrXHR.statusText;
            let lua_json = null;
            if (this._responseType === "json") {
                lua_json = JSON.parse(response);

            } else {
                lua_json = response;
            }
            if(!lua_json) {
                CustomEventListener.dispatchEvent("core_notify_http_response_failed", {
                        "event_name": this._eventName,
                        "response_data": "解析格式错误!"
                    });
                this._xhrXHR = null;
                console.warn("event_name:"+this._eventName+"解析格式错误!");
                return;
            }
            console.log("http response ", JSON.stringify(response), response_status, lua_json["code"], lua_json.code, this._eventName);

            this._succHandle(lua_json, this._eventName);
        } else {
            this._failHandle(this._xhrXHR.status, this._eventName);
        }
        // } else if (this._xhrXHR.status === 401) {
        //     console.log()
    }

    doXHRTimeout() {
        CustomEventListener.dispatchEvent("core_notify_http_response_failed", {
            "event_name": this._eventName,
            "response_data": "获取数据超时"
        })
        // this._xhrXHR.abort();
        this._xhrXHR = null;
    }

    validate() {
        if(!this._url) {
            console.warn("http none url init, return");
            return false;
        }
        if (this._url.slice(0, 4) !== "http") {
            console.warn("http err url init, return:"+this._url);
            return false;
        }
        if (this._method === "POST" && !this._requestData) {
            return false;
        }
        return true;
    }
}
